package com.access.boot.autoconfigure.apisdk.proxy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import java.util.Objects;

/**
 * @author Yangzhen
 * @date 2022/5/28 15:11
 * @since 1.0.0
 */
public class AccessorProxyBean<T> implements FactoryBean<T>, ApplicationContextAware, InitializingBean,
        ApplicationListener<ApplicationEvent> {

    private ApplicationContext ctx;

    /**
     * 原始 bean class
     */
    private Class<T> sourceClass;

    /**
     * 代理 bean
     */
    private T proxyBean;

    private AccessorFactory accessorFactory;

    public static String accessFactoryName;

    public AccessorProxyBean(Class<T> sourceClass) {
        this.sourceClass = sourceClass;
    }

    @Override
    public T getObject() throws Exception {
        if (Objects.isNull(accessorFactory)) {
            afterPropertiesSet();
        }
        if (Objects.isNull(proxyBean)) {
            // 初始化 open api
            proxyBean = accessorFactory.create(sourceClass);
        }
        return proxyBean;
    }

    @Override
    public Class<T> getObjectType() {
        return this.sourceClass;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (Objects.isNull(accessorFactory) && Objects.nonNull(ctx)) {
            // 获取 AccessorFactory，用于初始化 open api
            accessorFactory = ctx.getBean(AccessorFactory.class);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ctx = applicationContext;
    }

    /**
     * ContextRefreshedEvent 后初始化 open api
     *
     * @param event
     */
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ContextRefreshedEvent) {
            if (Objects.isNull(proxyBean)) {
                proxyBean = accessorFactory.create(sourceClass);
            }
        }
    }
}
